home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / util / misc / Kurta.lha / Kurta.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-19  |  13.3 KB  |  414 lines

  1. /*------- 
  2.  *  Kurta "Series One" driver
  3.  *
  4.  *  Please do not look too closely at this code, as it could
  5.  * cause health problems for those who cannot tolerate a lot
  6.  * of laughing.  In other words, this codes is pretty ugly
  7.  * and probably wont be of much use to anyone.
  8.  * If you make any changes to this driver, please let me know
  9.  * what you did to improve/change it.  The driver does need a
  10.  * lot of work, but is does it's minimal job of sending mouse
  11.  * events.
  12.  */
  13. #include <DOS/DOS.h>
  14. #include <Devices/Serial.h>
  15. #include <Devices/Input.h>
  16. #include <Devices/InputEvent.h>
  17. #include <Exec/IO.h>
  18. #include <Exec/Lists.h>
  19. #include <Exec/Memory.h>
  20. #include <Exec/Devices.h>
  21. #include <Exec/Libraries.h>
  22. #include <Libraries/Commodities.h>
  23. #include <Libraries/DOSExtens.h>
  24. #include <WorkBench/Startup.h>
  25. #include <CLib/ALib_protos.h>
  26. #include <Proto/Commodities.h>
  27. #include <Proto/DOS.h>
  28. #include <Proto/Exec.h>
  29. #include <Proto/Intuition.h>
  30.  
  31. #define    ABSEXECBASE ((struct ExecBase **)4L)
  32.  
  33. #define    READ_BUFFER     5    // Each command is 5 bytes long.
  34. /*------------------  FORMAT3 Settings -----------------------------*/
  35. #define    BUTTON_GRN     1 // m 0001    m = Menu
  36. #define    BUTTON_RED     2 // m 0010    bit 7 always = 1
  37. #define    BUTTON_BLU     4 // m 0100    bit 6 always = 0
  38. #define    BUTTON_YLW     8 // m 1000
  39. #define    MENUSTRIP        32 // M xxxx    bit 4 = menu Y/N
  40. #define    CMD_SIZE         7 // Hi bits shifted Left 6 (128).
  41. #define    MAXVALUE        127 // = 1<<CMD_SIZE-1
  42. /*------------------------------------------------------------------*/
  43. #define    BUTTONS        (BUTTON_GRN|BUTTON_RED|BUTTON_BLU|BUTTON_YLW)
  44. #define    BUTTON_MID    BUTTON_RED
  45. #define    BUTTON_LEFT    BUTTON_GRN    // Its not the left, but it is always Button 1
  46. #define    BUTTON_DOWN    BUTTON_BLU
  47. #define    BUTTON_RIGHT    BUTTON_YLW
  48. #define    MY_MOUSEMOVE    1    //  If any values change from
  49. #define    MY_BUTTONEVENT 2    // the previous, then I must send
  50. #define    MENU_FUNCTION    4    // an InputEvent to handler.
  51. #define    TABLET_LORES  1200    // 100ppi for 12inches
  52. #define    TABLET_HIRES    2400 // 200ppi for 12inches
  53.  
  54. struct Command
  55. {
  56.     UBYTE Buttons; //    Value = 1, 2, 4, 8, or 0-15 combo.
  57.     UBYTE pButtons; //    Previous buttons.  Used for MOUSEUP/DOWN changes.
  58.     UBYTE Menu;    //    Menu F0-F11
  59.     UBYTE MButtons; //    Keep menu button presses separate.
  60.     WORD X, Y;    //    Coordinates
  61.     WORD pX, pY;    //    Previous coordinates. Used for DELTA values.
  62. };
  63.  
  64. struct DosLibrary     *DOSBase;
  65. struct IntuitionBase  *IntuitionBase;
  66. struct Library     *CxBase, *IconBase;
  67. extern struct WBStartup *WBenchMsg;
  68.  
  69. UWORD  GetKurta(UBYTE *, struct Command *);
  70. ULONG  DoKMenu(struct Command *);
  71.  
  72. BOOL ExitFlag = 0;
  73. struct MsgPort *broker_mp;
  74. CxObj *broker, *filter, *sender, *translate;
  75. struct NewBroker newbroker =
  76. {
  77.     NB_VERSION,
  78.     "Kurta_Driver",
  79.     "Kurta Drawing Pad Driver",
  80.     "Commodity for Kurta Drawing Pad",
  81.     NBU_UNIQUE | NBU_NOTIFY,
  82.     0, 0, 0, 0
  83. };
  84. struct InputEvent *ie;
  85. ULONG cxsigflag;
  86.  
  87. __saveds Kurta(void)
  88. {
  89.     struct IOExtSer   *sio;    //  Serial IO request.
  90.     struct MsgPort       *smp;    //  Serial MsgPort.
  91.     struct IOStdReq   *iio;    //  Input IO request.
  92.     struct MsgPort       *imp;    //  Input MsgPort.
  93.     struct InputEvent *myevent;    // My fake input event.
  94.     struct IEPointerTablet *iep;    // My new pointer pixel positions.
  95.     struct Command      c; // What happened on the tablet.
  96.     UBYTE  readbuffer[READ_BUFFER];    // Serial data from tablet.
  97.     ULONG  result;
  98.     ULONG  waitmask;
  99.     UWORD  kevent;     // Has there been any events from Kurta()?
  100.     UWORD  bmask;        // Holds which buttons have changed since last message.
  101.     ULONG  msgid, msgtype;
  102.     CxMsg  *msg;
  103.  
  104.     struct Process *proc;
  105.     struct Message *WBMsg = NULL;
  106.  
  107.     proc = (struct Process *)FindTask(NULL); // Who/Where am I?
  108.     if( !proc->pr_CLI )        // Am I started from a CLI?
  109.     {
  110.         WaitPort(&proc->pr_MsgPort);    // NO? Well then get WBStartup Msg.
  111.         WBMsg = GetMsg(&proc->pr_MsgPort);
  112.     }
  113.  
  114.     DOSBase=(struct DosLibrary *)OpenLibrary("dos.library", 37);
  115.     if( !DOSBase ) // No startup code, get DOSBase my self
  116.         return(-1);
  117.  
  118.     if( smp = (struct MsgPort *)CreatePort("Kurta_Serial", 0) )
  119.     {
  120.         if( imp = (struct MsgPort *)CreatePort("Kurta_Input", 0) )
  121.         {
  122.             if( sio=(struct IOExtSer *)CreateExtIO(smp, sizeof(struct IOExtSer)) )
  123.             {
  124.                 if( myevent= (struct InputEvent *)AllocVec(sizeof(struct InputEvent), MEMF_PUBLIC) )
  125.                 {
  126.                     if( iep = (struct IEPointerTablet *)AllocVec(sizeof(struct IEPointerTablet), MEMF_PUBLIC) )
  127.                     {
  128.           if (iio = (struct IOStdReq *)CreateIORequest(imp,sizeof(struct IOStdReq)))
  129.           {
  130.             if( !OpenDevice("input.device", NULL,
  131.                                 (struct IORequest *)iio, NULL) )
  132.             {
  133.                 if( IntuitionBase = (struct IntuitionBase *)
  134.                             OpenLibrary("intuition.library", 36L) )
  135.                 {
  136.                                     sio->io_SerFlags = 0;
  137.                                     if( !OpenDevice(SERIALNAME, NULL, sio, NULL) )
  138.                                     {
  139.                                         sio->IOSer.io_Command  = SDCMD_SETPARAMS;
  140.                                         sio->io_SerFlags      &= ~SERF_PARTY_ON;
  141.                                         sio->io_SerFlags      |= SERF_XDISABLED | SERF_SHARED;
  142.                                         sio->io_Baud           = 9600;
  143.                                         if( !(result=DoIO(sio)) )
  144.                                         {
  145.                                     /*** Put commodity startup here  ***/
  146.         if (CxBase = OpenLibrary("commodities.library", 37L))
  147.         {
  148.             if (broker_mp = CreateMsgPort())
  149.             {
  150.                 newbroker.nb_Port = broker_mp;
  151.  
  152.                 if (broker = CxBroker(&newbroker, NULL))
  153.                 {
  154.                         ActivateCxObj(broker, 1L);
  155.  
  156.                                             waitmask = SIGBREAKF_CTRL_C | 1L<<smp->mp_SigBit | (1L << broker_mp->mp_SigBit);
  157. /*---------------Initialization complete------------------------------------*/
  158.                                             /*  Now just wait until data comes in, or user breaks. */
  159.                                             while( !ExitFlag )
  160.                                             {
  161.                                                 sio->IOSer.io_Command  = CMD_READ;
  162.                                                 sio->IOSer.io_Length   = READ_BUFFER;
  163.                                                 sio->IOSer.io_Data       = (APTR)readbuffer;
  164.                                                 SendIO(sio);
  165.                                                 result = Wait(waitmask); // Sit and wait...
  166.                                                 if( ExitFlag||(result & SIGBREAKF_CTRL_C) )    // Quit
  167.                                                     break;
  168.             if( result & (1L<<broker_mp->mp_SigBit) )
  169.             {
  170.             while(msg = (CxMsg *)GetMsg(broker_mp))
  171.             {
  172.  
  173.             msgid = CxMsgID(msg);
  174.             msgtype = CxMsgType(msg);
  175.             ReplyMsg((struct Message *)msg);
  176.  
  177.             switch(msgtype)
  178.             {
  179.                 case CXM_IEVENT:
  180.                     /* Shouldn't get any of these in this example */
  181.                     break;
  182.                 case CXM_COMMAND:
  183.                     /* Commodities has sent a command */
  184.                     switch(msgid)
  185.                     {
  186.                         case CXCMD_DISABLE:
  187.                             /* The user clicked Commodities Exchange disable
  188.                              * gadget better disable
  189.                              */
  190.                             ActivateCxObj(broker, 0L);
  191.                             break;
  192.                         case CXCMD_ENABLE:
  193.                             /* user clicked enable gadget */
  194.                             ActivateCxObj(broker, 1L);
  195.                             break;
  196.                         case CXCMD_KILL:
  197.                             /* user clicked kill gadget, better quit */
  198.                             ExitFlag=TRUE;
  199.                             break;
  200.                     }
  201.                     break;
  202.                 default:
  203. //                    kprintf("Unknown msgtype\n");
  204.                     break;
  205.             }
  206.             break;
  207.         }
  208.         }
  209.  
  210.                                                 if( CheckIO(sio) )
  211.                                                 {
  212.                                                 WaitIO(sio);
  213.                                                 if( sio->IOSer.io_Actual = 5 )
  214.                                                 {
  215.                                                     kevent = GetKurta(readbuffer, &c);
  216.                                                   if( kevent&MENU_FUNCTION )
  217.                                                     {
  218.                                                         if( c.Menu==11 )
  219.                                                         {
  220.                                                             ExitFlag = TRUE;
  221.                                                             break;
  222.                                                         }
  223.                                                         myevent->ie_Class = IECLASS_RAWKEY; /* new mouse pos */
  224.                                                         myevent->ie_SubClass = NULL;
  225.                                                         myevent->ie_Code = c.Menu+0x4F;
  226.                                                         myevent->ie_Qualifier = NULL;
  227.                                                         myevent->ie_EventAddress = (APTR)iep; /* IEPointerTablet */
  228.                                                         myevent->ie_NextEvent = NULL;
  229.                                                         iio->io_Data = (APTR)myevent;      /* InputEvent */
  230.                                                         iio->io_Length = sizeof(struct InputEvent);
  231.                                                         iio->io_Command = IND_WRITEEVENT;
  232.  
  233.                                                         DoIO((struct IORequest *)iio);
  234.                                                     }
  235.                                                                 //result = DoKMenu(&c);
  236.                                                     else
  237.                                                     {
  238.                                                         if( kevent & MY_MOUSEMOVE )
  239.                                                         {
  240.                                                             myevent->ie_Class = IECLASS_NEWPOINTERPOS; /* new mouse pos */
  241.                                                             myevent->ie_SubClass = IESUBCLASS_TABLET;   /* on pixel */
  242.                                                             myevent->ie_Code = IECODE_NOBUTTON;
  243.                                                             myevent->ie_Qualifier = NULL;
  244.                                                             myevent->ie_EventAddress = (APTR)iep; /* IEPointerTablet */
  245.                                                             myevent->ie_NextEvent = NULL;
  246.                                                             iio->io_Data = (APTR)myevent;      /* InputEvent */
  247.                                                             iio->io_Length = sizeof(struct InputEvent);
  248.                                                             iio->io_Command = IND_WRITEEVENT;
  249.                                                             iep->iept_Range.X = TABLET_LORES;
  250.                                                             iep->iept_Range.Y = TABLET_LORES;
  251.                                                             iep->iept_Value.X = c.X;
  252.                                                             iep->iept_Value.Y = c.Y;
  253.                                                             iep->iept_Pressure    = NULL;    // Not implemented.
  254.  
  255.                                                             DoIO((struct IORequest *)iio);
  256.                                                         }
  257.                                                         if( kevent & MY_BUTTONEVENT ) // TABLET cannot do Buttons.
  258.                                                         {
  259.                                                             bmask = c.Buttons ^ c.pButtons;
  260.                                                             myevent->ie_Class = IECLASS_RAWMOUSE;
  261.                                                             myevent->ie_SubClass = NULL;
  262.                                                             myevent->ie_Code = IECODE_NOBUTTON;
  263.                                                             myevent->ie_Qualifier = NULL;
  264.                                                             myevent->ie_EventAddress = NULL;
  265.                                                             myevent->ie_NextEvent = NULL;
  266.                                                             iio->io_Data = (APTR)myevent;      /* InputEvent */
  267.                                                             iio->io_Length = sizeof(struct InputEvent);
  268.                                                             iio->io_Command = IND_WRITEEVENT;
  269.                                                             if( bmask & BUTTON_LEFT )
  270.                                                             {
  271.                                                                 myevent->ie_Code = IECODE_LBUTTON;
  272.                                                                 if( !(c.Buttons & BUTTON_LEFT) )
  273.                                                                     myevent->ie_Code |= IECODE_UP_PREFIX;
  274.                                                             }
  275.                                                             else
  276.                                                             if( bmask & BUTTON_RIGHT )
  277.                                                             {
  278.                                                                 myevent->ie_Code = IECODE_RBUTTON;
  279.                                                                 if( !(c.Buttons & BUTTON_RIGHT) )
  280.                                                                     myevent->ie_Code |= IECODE_UP_PREFIX;
  281.                                                             }
  282.                                                             else
  283.                                                             if( bmask & BUTTON_MID )
  284.                                                             {
  285.                                                                 myevent->ie_Code = IECODE_MBUTTON;
  286.                                                                 if( !(c.Buttons & BUTTON_MID) )
  287.                                                                     myevent->ie_Code |= IECODE_UP_PREFIX;
  288.                                                             }
  289.  
  290.                                                             DoIO((struct IORequest *)iio);
  291.                                                         }
  292.                                                     }
  293.                                                 }
  294.                                                 else return(2);    //    printf("Bad Command.\n");
  295.                                                 }
  296.  
  297.                                             }
  298.                                             DisplayBeep(NULL);
  299.                                             AbortIO(sio);    // Clean up port and quit.
  300.                                             WaitIO(sio);
  301.                                             DisplayBeep(NULL);
  302.  
  303. /*-----------------Cleanup starts here--------------------------------------*/
  304.                                     /*** Put commodity teardown here  ***/
  305.                 DeleteCxObj(broker);
  306.  
  307.                 while(msg = (CxMsg *)GetMsg(broker_mp))
  308.                         ReplyMsg((struct Message *)msg);
  309.             }
  310.             DeletePort(broker_mp);
  311.         }
  312.         CloseLibrary(CxBase);
  313.     }
  314.  
  315.                                         }
  316.                                         else
  317.                                             return(3);    //printf("Could not set Serial Params.\n");
  318.                                         CloseDevice(sio);
  319.                                     }
  320.                                     else
  321.                                         return(4);    //printf("Could not open serial.device.\n");
  322.                                     CloseLibrary(IntuitionBase);
  323.                                 }
  324.                                 else
  325.                                     return(5);    //printf("Could not open IntuitionBase.\n");
  326.                             CloseDevice((struct IORequest *)iio);
  327.                             }
  328.                             else
  329.                                 return(6);    //printf("Could no OpenDevice for iio.\n");
  330.                             DeleteIORequest(iio);
  331.                         }
  332.                         else
  333.                             return(7);    //printf("Could not CreateIORequest(Input).\n");
  334.                         FreeVec(iep);
  335.                     }
  336.                     else
  337.                         return(8);    //printf("Could not AllocMem 'iep'.\n");
  338.                     FreeVec(myevent);
  339.                 }
  340.                 else
  341.                     return(9);    //printf("Could not AllocMem for 'myevent'.\n");
  342.                 DeleteExtIO(sio);
  343.             }
  344.             else
  345.                 return(10);    //printf("Could not Create[serial]ExtIO.\n");
  346.             DeletePort(imp);
  347.         }
  348.         else
  349.             return(11);    //printf("Could not CreatePort(Kurta_Input)\.\n");
  350.         DeletePort(smp);
  351.     }
  352.     else
  353.         return(12);    //printf("Could not CreatePort(Kurta_Serial)\n");
  354.     if( DOSBase )    CloseLibrary(DOSBase);
  355.   if( WBMsg )    // Hey! We were started from WB, clean up.
  356.     {
  357.         Forbid();
  358.         ReplyMsg(WBMsg);
  359.         Permit();
  360.   }
  361.  
  362.     return(0);    // Remember to exit from Main or program will continue...
  363. }
  364.  
  365. UWORD
  366. GetKurta(UBYTE *cmd, struct Command *c)
  367. {
  368.     UWORD event = 0;
  369.     static    UBYTE  accel=0;    // Immitate a mouse accelerator for the tablet.
  370.  
  371.   /*     Save all previous stats     */
  372.     c->pX = c->X;
  373.     c->pY = c->Y;
  374.     c->pButtons = c->Buttons;
  375.     if( cmd[0]&MENUSTRIP )
  376.     {
  377.         c->Menu = (cmd[1]&MAXVALUE) - 0x0A; //    Which menu (0-11).
  378.         c->MButtons = (cmd[0]&BUTTONS)|(cmd[2]&MAXVALUE)<<CMD_SIZE;
  379.         if( c->Menu == 0 )
  380.         {
  381.             accel++; if( accel >2 ) accel = 0;     // 0,1,2 (x << accel = 1, 2, 4 )
  382.             DisplayBeep(NULL);
  383.         }
  384.         else
  385.             event |= MENU_FUNCTION;
  386.     }
  387.     else
  388.     {
  389.         c->Buttons = (cmd[0]&BUTTONS); // Buttons currently pressed
  390.         c->X = ((cmd[1]&MAXVALUE) | (cmd[2]&MAXVALUE)<<CMD_SIZE)<<accel;
  391.         c->Y = ((cmd[3]&MAXVALUE) | (cmd[4]&MAXVALUE)<<CMD_SIZE)<<accel;
  392.         if( c->X < 0 )     c->X = 0;
  393.         if( c->Y < 0 )     c->Y = 0;
  394.         if( (c->pX != c->X)||(c->pY != c->Y) ) //  Send input events if
  395.             event |= MY_MOUSEMOVE;        // if any event differs
  396.         if( c->pButtons != c->Buttons )        // from the previous.
  397.             event |= MY_BUTTONEVENT;        //
  398.     }
  399.  
  400.     return(event);
  401. }
  402.  
  403. ULONG
  404. DoKMenu(struct Command *c)
  405. {
  406.     if( c->Menu == 11 )
  407.         ExitFlag = TRUE;
  408.  
  409.         DisplayBeep(NULL);
  410.  
  411.     return(ExitFlag);
  412. }
  413.  
  414.